/*
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
参数：
target: 对于静态成员来说是类的构造函数，对于实例成员是类的原型对象
*/


//--------------------------------------------------------------------
/*
类装饰器
给类 添加额外属性和方法
*/
function addInfoToClass(target:Function) {
  target.prototype.additionalProperty = 'Additional Property';

  target.prototype.additionalMethod = function () {
    console.log('Additional Method');
  };
}


@addInfoToClass
class MyClass {
  existingProperty: string;

  constructor(existingProperty: string) {
    this.existingProperty = existingProperty;
  }

  existingMethod() {
    console.log('Existing Method');
  }
}

const instance:MyClass = new MyClass('Existing Property');

console.log(instance.existingProperty); // Output: Existing Property
console.log((<any>instance).additionalProperty); // Output: Additional Property

instance.existingMethod(); // Output: Existing Method
(<any>instance).additionalMethod(); // Output: Additional Method
//----------------------------------------------------------------------------



//------------------------------------------------------------------------------------------
const musicDecorator : ClassDecorator = (target:Function)=>{  
  target.prototype.playPiano = () => {
    console.log('弹钢琴');
  }
}

@musicDecorator
class Student {

}

@musicDecorator
class Artist{
  
}

var xiaoming = new Student();
(<any>xiaoming).playPiano()

var jay = new Artist();
(<any>jay).playPiano()


function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
  return class extends constructor {
      newProperty = "new property";
      hello = "override";
  }
}

@classDecorator
class Greeter {
  property = "property";
  hello: string;
  constructor(m: string) {
      this.hello = m;
  }
}

const greeter = new Greeter("world");
console.log((<any>greeter).newProperty)
console.log((<any>greeter).property)
console.log((<any>greeter).hello)
//------------------------------------------------------------------------------------------